package com.genericdevice.platform.core.menu;

import android.app.Activity;
import android.view.Menu;
import android.view.MenuInflater;
import com.genericdevice.platform.core.exceptions.UnsupportedOperation;
import com.genericdevice.platform.core.logging.LoggerHelper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Xilent on 17.05.2014.
 */
public class OptionsMenuBuilder {

    private static Map<String, OptionsMenuBuilder> MAIN_INSTANCES = new HashMap<String, OptionsMenuBuilder>();
    private static Map<String, Map<String, OptionsMenuBuilder>> INSTANCES = new HashMap<String, Map<String, OptionsMenuBuilder>>();
    private static LoggerHelper LOGGER = LoggerHelper.getInstance();

    private String name;
    private Menu menu;
    private MenuInflater infletter;
    private Integer menuId;
    private Activity activity;

    private OptionsMenuConfig config;

    public static OptionsMenuBuilder getInstance(String name) {
        OptionsMenuBuilder instance = MAIN_INSTANCES.get(name);
        if (instance == null) {
            instance = new OptionsMenuBuilder(name);
            MAIN_INSTANCES.put(name, instance);
        }

        return instance;
    }

    public static OptionsMenuBuilder getChildInstance(String parent, String name) {
        Map<String, OptionsMenuBuilder> instances = INSTANCES.get(parent);
        if (instances == null) {
            instances = new HashMap<String, OptionsMenuBuilder>();
            INSTANCES.put(parent, instances);
        }

        OptionsMenuBuilder menuBuilder = instances.get(name);
        if (menuBuilder == null) {
            menuBuilder = new OptionsMenuBuilder(name);
            instances.put(name, menuBuilder);
        }

        return menuBuilder;
    }

    private OptionsMenuBuilder(String name) {
        this.name = name;
    }

    public void setCreatedMenu(Menu menu) throws UnsupportedOperation {
        if (!MAIN_INSTANCES.containsKey(name))
            throw new UnsupportedOperation("Changing of options menu supported only by main instances");

        this.menu = menu;
    }

    public void setMenuInfletter(MenuInflater infletter) throws UnsupportedOperation {
        if (!MAIN_INSTANCES.containsKey(name))
            throw new UnsupportedOperation("Changing of options menu supported only by main instances");

        this.infletter = infletter;
    }

    public void setMenuId(int menuId) {
        this.menuId = menuId;
    }

    public Integer getMenuId() {
        return menuId;
    }

    public void setConfigData(int resourceId, Class ids) {
        config = OptionsMenuConfig.getInstance(resourceId, ids);
        config.setActivity(activity);
        config.init();
    }

    public void setActivity(Activity activity) {
        this.activity = activity;
    }

    public OptionsMenuConfig getConfig() {
        return config;
    }

    public List<OptionsMenuConfig> getOptionsMenuConfigs() throws UnsupportedOperation {
        if (!MAIN_INSTANCES.containsKey(name))
            throw new UnsupportedOperation("Changing of options menu supported only by main instances");

        List<OptionsMenuConfig> configs = new ArrayList<OptionsMenuConfig>();

        Map<String, OptionsMenuBuilder> instances = INSTANCES.get(name);

        if (instances == null)
            instances = new HashMap<String, OptionsMenuBuilder>();

        instances.put(name, this);

        for (Map.Entry<String, OptionsMenuBuilder> builder : instances.entrySet()) {
            OptionsMenuConfig config = builder.getValue().getConfig();
            if (config != null)
                configs.add(config);
        }

        return configs;
    }

    public void clearBuilders() throws UnsupportedOperation {
        if (!MAIN_INSTANCES.containsKey(name))
            throw new UnsupportedOperation("Changing of options menu supported only by main instances");

        Map<String, OptionsMenuBuilder> instances = INSTANCES.get(name);
        if (instances != null) instances.clear();

        INSTANCES.values().remove(this);
    }

    public void buildItems() throws UnsupportedOperation {
        if (!MAIN_INSTANCES.containsKey(name))
            throw new UnsupportedOperation("Changing of options menu supported only by main instances");

        menu.clear();

        infletter.inflate(getMenuId(), menu);

        Map<String, OptionsMenuBuilder> instances = INSTANCES.get(name);
        if (instances == null)
            return;

        for (Map.Entry<String, OptionsMenuBuilder> builder : instances.entrySet()) {
            LOGGER.log("Found options menu builder \"" + builder.getKey() + "\"");
            Integer id = builder.getValue().getMenuId();
            infletter.inflate(id, menu);
        }
    }
}
